home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / database / cmd.c < prev    next >
Text File  |  1984-05-21  |  21KB  |  850 lines

  1. /* SDB - command parser */
  2.  
  3. #include "stdio.h"
  4. #include "sdbio.h"
  5. #include "ctype.h"
  6.  
  7. extern int dbv_token;
  8. extern char dbv_tstring[];
  9. extern int dbv_tvalue;
  10. extern struct ifile *dbv_ifp;
  11. extern struct macro *dbv_macros;
  12. extern int dbv_fold;
  13.  
  14. #ifdef Lattice
  15. int _fmode = 0;  /*dns*/
  16. #endif
  17.  
  18. /* db_parse - parse a command */
  19. int db_parse(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
  20.   char *fmt;
  21. {
  22.     int sts;
  23.  
  24.     /* check for a command line */
  25.     if (fmt != NULL)
  26.         db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);
  27.  
  28.     /* determine the statement type */
  29.     switch (db_ntoken()) {
  30.     case ';':   sts = TRUE;
  31.                 break;
  32.     case COMPRESS:
  33.                 sts = db_squeeze(NULL);
  34.                 break;
  35.     case CREATE:
  36.                 sts = create();
  37.                 break;
  38.     case DEFINE:
  39.                 sts = mc_define();
  40.                 break;
  41.     case DELETE:
  42.                 sts = delete();
  43.                 break;
  44.     case EXIT:
  45.                 exit();
  46.     case EXPORT:
  47.                 sts = db_export(NULL);
  48.                 break;
  49.     case EXTRACT:
  50.                 sts = db_extract(NULL);
  51.                 break;
  52.     case HELP:
  53.                 sts = help();
  54.                 break;
  55.     case IMPORT:
  56.                 sts = db_import(NULL);
  57.                 break;
  58.     case INSERT:
  59.                 sts = insert();
  60.                 break;
  61.     case PRINT:
  62.                 sts = print();
  63.                 break;
  64.     case SELECT:
  65.                 sts = select();
  66.                 break;
  67.     case SET:
  68.                 sts = set();
  69.                 break;
  70.     case SHOW:
  71.                 sts = mc_show();
  72.                 break;
  73.     case SORT:
  74.                 sts = db_sort(NULL);
  75.                 break;
  76.     case UPDATE:
  77.                 sts = update();
  78.                 break ;
  79.     default:
  80.                 return (db_ferror(SYNTAX));
  81.     }
  82.  
  83.     return (sts);
  84. }
  85.  
  86. /* help - print a short help message */
  87. static int help()
  88. {
  89.     FILE *fp;
  90.     int ch;
  91.  
  92.     if ((fp = fopen("sdb.hlp","r")) != NULL) {
  93.      /* while ((ch = agetc(fp)) != EOF)    dns */
  94.         while ((ch =  getc(fp)) != EOF)
  95.             putchar(ch);
  96.         fclose(fp);
  97.     }
  98.     else
  99.         printf("No online help available.  Read the manual\n");
  100.  
  101.     /* return successfully */
  102.     return (TRUE);
  103. }
  104.  
  105. /* create - create a new relation */
  106. static int create()
  107. {
  108.     struct relation *rptr;
  109.     char aname[STRINGMAX+1];
  110.     int atype;
  111.  
  112.     /* get relation name */
  113.     if (db_ntoken() != ID)
  114.         return (db_ferror(SYNTAX));
  115.  
  116.     /* start relation creation */
  117.     if ((rptr = db_rcreate(dbv_tstring)) == NULL)
  118.         return (FALSE);
  119.  
  120.     /* check for attribute list */
  121.     if (db_ntoken() != '(') {
  122.         free(rptr);
  123.         return (db_ferror(SYNTAX));
  124.     }
  125.  
  126.     /* parse the attributes */
  127.     while (TRUE) {
  128.  
  129.         /* get the attribute name */
  130.         if (db_ntoken() != ID) {
  131.             free(rptr);
  132.             return (db_ferror(SYNTAX));
  133.         }
  134.         strcpy(aname,dbv_tstring);
  135.  
  136.         /* get the attribute type */
  137.         db_ntoken();
  138.         if (dbv_token == CHAR)
  139.             atype = TCHAR;
  140.         else if (dbv_token == NUM)
  141.             atype = TNUM;
  142.         else {
  143.             free(rptr);
  144.             return (db_ferror(SYNTAX));
  145.         }
  146.  
  147.         /* get the attribute size */
  148.         if (db_ntoken() != NUMBER) {
  149.             free(rptr);
  150.             return (db_ferror(SYNTAX));
  151.         }
  152.  
  153.         /* add the attribute */
  154.         if (!db_rcattr(rptr,aname,atype,dbv_tvalue)) {
  155.             free(rptr);
  156.             return (FALSE);
  157.         }
  158.  
  159.         /* check for end of attributes */
  160.         if (db_token() != ID)
  161.             break;
  162.     }
  163.  
  164.     /* check for attribute list end */
  165.     if (db_ntoken() != ')') {
  166.         free(rptr);
  167.         return (db_ferror(SYNTAX));
  168.     }
  169.  
  170.     /* check for relation size */
  171.     if (db_ntoken() != NUMBER) {
  172.         free(rptr);
  173.         return (db_ferror(SYNTAX));
  174.     }
  175.  
  176.     /* finish relation creation */
  177.     if (!db_rcheader(rptr))
  178.         return (FALSE);
  179.     if (!db_rctuples(rptr,dbv_tvalue))
  180.         return (FALSE);
  181.     if (!db_rcdone(rptr))
  182.         return (FALSE);
  183.  
  184.     /* return successfully */
  185.     return (TRUE);
  186. }
  187.  
  188. /* insert - insert a tuple into a relation */
  189. static int insert()
  190. {
  191.     struct scan *sptr;
  192.     struct attribute *aptr;
  193.     char aname[ANSIZE+1],avalue[STRINGMAX+1];
  194.     int tcnt,astart,i;
  195.  
  196.     /* get relation name */
  197.     if (db_token() == ID)
  198.         db_ntoken();
  199.     else
  200.         strcpy(dbv_tstring,"sdbcur");
  201.  
  202.     /* make sure that the rest of the line is blank */
  203.     if (!db_flush())
  204.         return (FALSE);
  205.  
  206.     /* open the relation */
  207.     if ((sptr = db_ropen(dbv_tstring)) == NULL)
  208.         return (FALSE);
  209.  
  210.     /* insert tuples */
  211.     for (tcnt = 0; ; tcnt++) {
  212.  
  213.         /* print separator if not the first tuple */
  214.         if (tcnt != 0)
  215.             printf("----\n");
  216.  
  217.         /* get attribute values */
  218.         astart = 1;
  219.         for (i = 0; i < NATTRS; i++) {
  220.  
  221.             /* get a pointer to the current attribute */
  222.             aptr = &sptr->sc_relation->rl_header.hd_attrs[i];
  223.  
  224.             /* check for the last attribute */
  225.             if (aptr->at_name[0] == 0)
  226.                 break;
  227.  
  228.             /* get the attribute name */
  229.             stccpy(aname,aptr->at_name,ANSIZE); aname[ANSIZE] = 0;
  230.  
  231.             /* setup null prompt strings */
  232.             db_prompt(NULL,NULL);
  233.  
  234.             /* prompt and input attribute value */
  235.             while (TRUE) {
  236.                 if (dbv_ifp == NULL)
  237.                     if (strlen(aname) < 8)
  238.                         printf("%s\t\t: ",aname);
  239.                     else
  240.                         printf("%s\t: ",aname);
  241.                 if (db_gline(avalue) != NULL)
  242.                     break;
  243.             }
  244.  
  245.             /* check for last insert */
  246.             if (i == 0 && avalue[0] == EOS)
  247.                 break;
  248.  
  249.             /* store the attribute value */
  250.             db_aput(aptr,&sptr->sc_tuple[astart],avalue);
  251.  
  252.             /* update the attribute start */
  253.             astart += aptr->at_size;
  254.         }
  255.  
  256.         /* check for last insert */
  257.         if (avalue[0] == EOS)
  258.             break;
  259.  
  260.         /* store the new tuple */
  261.         if (!db_rstore(sptr)) {
  262.             db_rclose(sptr);
  263.             return (FALSE);
  264.         }
  265.     }
  266.  
  267.     /* close the relation */
  268.     db_rclose(sptr);
  269.  
  270.     /* check number of tuples inserted */
  271.     if (tcnt != 0) {
  272.  
  273.         /* print tuple count */
  274.         printf("[ %d inserted ]\n",tcnt);
  275.     }
  276.     else
  277.         printf("[ none inserted ]\n");
  278.  
  279.     /* return successfully */
  280.     return (TRUE);
  281. }
  282.  
  283. /* delete - delete tuples from a relation */
  284. static int delete()
  285. {
  286.     struct sel *slptr;
  287.     struct srel *srptr;
  288.     int tcnt;
  289.  
  290.     /* parse the retrieval clause */
  291.     if ((slptr = db_retrieve(NULL)) == NULL)
  292.         return (FALSE);
  293.  
  294.     /* loop through the retrieved tuples */
  295.     for (tcnt = 0; db_fetch(slptr); tcnt++)
  296.  
  297.         /* delete the retrieved tuples */
  298.         for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
  299.             if (!db_rdelete(srptr->sr_scan)) {
  300.                 db_done(slptr);
  301.                 return (FALSE);
  302.             }
  303.  
  304.     /* finish the retrieval */
  305.     db_done(slptr);
  306.  
  307.     /* check number of tuples deleted */
  308.     if (tcnt != 0) {
  309.  
  310.         /* print tuple count */
  311.         printf("[ %d deleted ]\n",tcnt);
  312.     }
  313.     else
  314.         printf("[ none deleted ]\n");
  315.  
  316.     /* return successfully */
  317.     return (TRUE);
  318. }
  319.  
  320. /* update - update tuples from a relation */
  321. static int update()
  322. {
  323.     struct sel *slptr;
  324.     struct sattr *saptr;
  325.     struct attribute *aptr;
  326.     char aname[ANSIZE+1],avalue[STRINGMAX+1],*ap;
  327.     int tcnt;
  328.  
  329.     /* parse the selection clause */
  330.     if ((slptr = db_select(NULL)) == NULL)
  331.         return (FALSE);
  332.  
  333.     /* make sure that the rest of the line is blank */
  334.     if (!db_flush()) {
  335.         db_done(slptr);
  336.         return (FALSE);
  337.     }
  338.  
  339.     /* loop through the selected tuples */
  340.     for (tcnt = 0; db_fetch(slptr); tcnt++) {
  341.  
  342.         /* print separator if not the first tuple */
  343.         if (tcnt != 0)
  344.             printf("----\n");
  345.  
  346.         /* loop through the selected attributes */
  347.         for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) {
  348.  
  349.             /* get the attribute pointer */
  350.             aptr = saptr->sa_attr;
  351.  
  352.             /* get the attribute name */
  353.             stccpy(aname,aptr->at_name,ANSIZE); aname[ANSIZE] = 0;
  354.  
  355.             /* get the attribute value */
  356.             db_aget(aptr,saptr->sa_aptr,avalue);
  357.             for (ap = avalue; isspace(*ap); ap++)
  358.                 ;
  359.  
  360.             /* print it */
  361.             if (strlen(aname) < 8)
  362.                 printf("%s\t\t: %s\n",aname,ap);
  363.             else
  364.                 printf("%s\t: %s\n",aname,ap);
  365.  
  366.             /* setup null prompt strings */
  367.             db_prompt(NULL,NULL);
  368.  
  369.             /* prompt and input attribute value */
  370.             while (TRUE) {
  371.                 if (strlen(aname) < 8)
  372.                     printf("%s\t\t: ",aname);
  373.                 else
  374.                     printf("%s\t: ",aname);
  375.                 if (db_gline(avalue) != NULL)
  376.                     break;
  377.             }
  378.  
  379.             /* store the attribute value */
  380.             if (avalue[0] != EOS) {
  381.                 db_aput(aptr,saptr->sa_aptr,avalue);
  382.                 saptr->sa_srel->sr_update = TRUE;
  383.             }
  384.         }
  385.  
  386.         /* update the tuples */
  387.         db_update(slptr);
  388.     }
  389.  
  390.     /* finish the selection */
  391.     db_done(slptr);
  392.  
  393.     /* check number of tuples updated */
  394.     if (tcnt != 0) {
  395.  
  396.         /* print tuple count */
  397.         printf("[ %d updated ]\n",tcnt);
  398.     }
  399.     else
  400.         printf("[ none updated ]\n");
  401.  
  402.     /* return successfully */
  403.     return (TRUE);
  404. }
  405.  
  406. /* print - print tuples from a set of relations */
  407. static int print()
  408. {
  409.     struct sel *slptr;
  410.     FILE *ffp,*ofp;
  411.     int tcnt;
  412.  
  413.     /* parse the using clause */
  414.     if (!using(&ffp,".frm"))
  415.         return (FALSE);
  416.  
  417.     /* parse the select clause */
  418.     if ((slptr = db_select(NULL)) == NULL)
  419.         return (FALSE);
  420.  
  421.     /* parse the into clause */
  422.     if (!db_to(&ofp,".txt")) {
  423.         db_done(slptr);
  424.         return (FALSE);
  425.     }
  426.  
  427.     /* check for normal or formated output */
  428.     if (ffp == NULL)
  429.         tcnt = table(ofp,slptr);
  430.     else
  431.         tcnt = form(ofp,slptr,ffp);
  432.  
  433.     /* finish the selection */
  434.     db_done(slptr);
  435.  
  436.     /* close the form definition file */
  437.     if (ffp != NULL)
  438.         fclose(ffp);
  439.  
  440.     /* close the output file */
  441.     if (ofp != stdout)
  442.         fclose(ofp);
  443.  
  444.     /* check number of tuples selected */
  445.     if (tcnt != 0)
  446.         printf("[ %d found ]\n",tcnt);
  447.     else
  448.         printf("[ none found ]\n");
  449.  
  450.     /* return successfully */
  451.     return (TRUE);
  452. }
  453.  
  454. /* select - select tuples from a set of relations */
  455. static int select()
  456. {
  457.     struct sel *slptr;
  458.     struct relation *rptr;
  459.     struct sattr *saptr;
  460.     char *aname,*tbuf;
  461.     int tcnt,abase,i;
  462.  
  463.     /* parse the select clause */
  464.     if ((slptr = db_select(NULL)) == NULL)
  465.         return (FALSE);
  466.  
  467.     /* create a new relation */
  468.     if ((rptr = db_rcreate("sdbcur")) == NULL) {
  469.         db_done(slptr);
  470.         return (FALSE);
  471.     }
  472.  
  473.     /* create the selected attributes */
  474.     for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) {
  475.  
  476.         /* decide which attribute name to use */
  477.         if ((aname = saptr->sa_name) == NULL)
  478.             aname = saptr->sa_aname;
  479.  
  480.         /* add the attribute */
  481.         if (!db_rcattr(rptr,aname,saptr->sa_attr->at_type,
  482.                                   saptr->sa_attr->at_size)) {
  483.             free(rptr);
  484.             db_done(slptr);
  485.             return (FALSE);
  486.         }
  487.     }
  488.  
  489.     /* create the relation header */
  490.     if (!db_rcheader(rptr)) {
  491.         db_done(slptr);
  492.         return (FALSE);
  493.     }
  494.  
  495.     /* allocate and initialize a tuple buffer */
  496.     if ((tbuf = calloc(1,rptr->rl_size)) == NULL) {
  497.         db_rcdone(rptr);
  498.         return (db_ferror(INSMEM));
  499.     }
  500.     tbuf[0] = ACTIVE;
  501.  
  502.     /* loop through the selected tuples */
  503.     for (tcnt = 0; db_fetch(slptr); tcnt++) {
  504.  
  505.         /* create the tuple from the selected attributes */
  506.         abase = 1;
  507.         for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) {
  508.             for (i = 0; i < saptr->sa_attr->at_size; i++)
  509.                 tbuf[abase + i] = saptr->sa_aptr[i];
  510.             abase += i;
  511.         }
  512.  
  513.         /* write the tuple */
  514.         if (write(rptr->rl_fd,tbuf,rptr->rl_size) != rptr->rl_size) {
  515.             db_rcdone(rptr);
  516.             free(tbuf);
  517.             return (db_ferror(INSBLK));
  518.         }
  519.         rptr->rl_tcnt++;
  520.         rptr->rl_tmax++;
  521.     }
  522.  
  523.     /* finish the selection */
  524.     db_done(slptr);
  525.  
  526.     /* finish relation creation */
  527.     if (!db_rcdone(rptr))
  528.         return (FALSE);
  529.  
  530.     /* check number of tuples selected */
  531.     if (tcnt != 0)
  532.         printf("[ %d found ]\n",tcnt);
  533.     else
  534.         printf("[ none found ]\n");
  535.  
  536.     /* return successfully */
  537.     return (TRUE);
  538. }
  539.  
  540. /* mc_define - define a macro */
  541. static int mc_define()
  542. {
  543.     struct macro *mptr,*mlast;
  544.     struct mtext *tptr,*tlast;
  545.     char textline[LINEMAX+1];
  546.  
  547.     /* get macro name */
  548.     if (db_xntoken() != ID)
  549.         return (db_ferror(SYNTAX));
  550.  
  551.     /* make sure that the rest of the line is blank */
  552.     if (!db_flush())
  553.         return (FALSE);
  554.  
  555.     /* find the macro in the macro table and free it */
  556.     for (mptr = dbv_macros, mlast = NULL; mptr != NULL; mlast = mptr, mptr = mptr->mc_next)
  557.         if (db_scmp(mptr->mc_name,dbv_tstring) == 0) {
  558.             if (mlast == NULL)
  559.                 dbv_macros = mptr->mc_next;
  560.             else
  561.                 mlast->mc_next = mptr->mc_next;
  562.             mc_free(mptr);
  563.         }
  564.  
  565.     /* allocate and initialize a macro structure */
  566.     if ((mptr = malloc(sizeof(struct macro))) == NULL)
  567.         return (db_ferror(INSMEM));
  568.     if ((mptr->mc_name = malloc(strlen(dbv_tstring)+1)) == NULL) {
  569.         free(mptr);
  570.         return (db_ferror(INSMEM));
  571.     }
  572.     strcpy(mptr->mc_name,dbv_tstring);
  573.     mptr->mc_mtext = NULL;
  574.  
  575.     /* setup null prompt strings */
  576.     db_prompt(NULL,"SDB-DEF> ");
  577.  
  578.     /* get definition text */
  579.     for (tlast = NULL; ; tlast = tptr) {
  580.  
  581.         /* get a line */
  582.         db_gline(textline);
  583.         if (textline[0] == EOS || textline[0] == '\n')
  584.             break;
  585.  
  586.         /* allocate a macro text structure */
  587.         if ((tptr = malloc(sizeof(struct mtext))) == NULL) {
  588.             mc_free(mptr);
  589.             return (db_ferror(INSMEM));
  590.         }
  591.         if ((tptr->mt_text = malloc(strlen(textline)+1)) == NULL) {
  592.             mc_free(mptr);
  593.             return (db_ferror(INSMEM));
  594.         }
  595.         strcpy(tptr->mt_text,textline);
  596.         tptr->mt_next = NULL;
  597.  
  598.         /* link it into the macro list */
  599.         if (tlast == NULL)
  600.             mptr->mc_mtext = tptr;
  601.         else
  602.             tlast->mt_next = tptr;
  603.     }
  604.  
  605.     /* link the new macro into the macro list */
  606.     if (tlast == NULL)
  607.         mc_free(mptr);
  608.     else {
  609.         mptr->mc_next = dbv_macros;
  610.         dbv_macros = mptr;
  611.     }
  612.  
  613.     /* return successfully */
  614.     return (TRUE);
  615. }
  616.  
  617. /* mc_show - show a macro */
  618. static int mc_show()
  619. {
  620.     struct macro *mptr;
  621.     struct mtext *tptr;
  622.  
  623.     /* get macro name */
  624.     if (db_xntoken() != ID)
  625.         return (db_ferror(SYNTAX));
  626.  
  627.     /* find the macro in the macro table */
  628.     for (mptr = dbv_macros; mptr != NULL; mptr = mptr->mc_next)
  629.         if (db_scmp(mptr->mc_name,dbv_tstring) == 0) {
  630.             for (tptr = mptr->mc_mtext; tptr != NULL; tptr = tptr->mt_next)
  631.                 printf("\t%s\n",tptr->mt_text);
  632.             break;
  633.         }
  634.  
  635.     /* check for successful search */
  636.     if (mptr == NULL)
  637.         printf("*** no macro named: %s ***\n",dbv_tstring);
  638.  
  639.     /* return successfully */
  640.     return (TRUE);
  641. }
  642.  
  643. /* mc_free - free a macro definition */
  644. static mc_free(mptr)
  645.   struct macro *mptr;
  646. {
  647.     struct mtext *tptr;
  648.  
  649.     while ((tptr = mptr->mc_mtext) != NULL) {
  650.         mptr->mc_mtext = tptr->mt_next;
  651.         free(tptr->mt_text);
  652.         free(tptr);
  653.     }
  654.     free(mptr->mc_name);
  655.     free(mptr);
  656. }
  657.  
  658. /* db_to - redirect output into a file */
  659. int db_to(pfp,ext)
  660.   FILE **pfp; char *ext;
  661. {
  662. #ifdef vms
  663.     int fd;
  664. #endif
  665.  
  666.     /* assume no into clause */
  667.     *pfp = stdout;
  668.  
  669.     /* check for "into <fname>" */
  670.     if (db_token() != INTO)
  671.         return (TRUE);
  672.     db_ntoken();
  673.     if (db_ntoken() == ID)
  674.         strcat(dbv_tstring,ext);
  675.     else if (dbv_token != STRING)
  676.         return (db_ferror(SYNTAX));
  677.  
  678.     /* open the output file */
  679. #ifdef vms
  680.     if ((fd = creat(dbv_tstring,0,"rfm=var","rat=cr")) == -1)
  681.         return (db_ferror(OUTCRE));
  682.     *pfp = fdopen(fd,"w");
  683. #else
  684. #ifdef Lattice
  685.     _fmode = 0x8000;  /*dns*/
  686. #endif
  687.     *pfp = fopen(dbv_tstring,"w");  /*dns*/
  688. #ifdef Lattice
  689.     _fmode = 0;       /*dns*/
  690. #endif
  691.     if (*pfp == NULL)               /*dns*/
  692.         return (db_ferror(OUTCRE)); /*dns*/
  693. #endif
  694.  
  695.     /* return successfully */
  696.     return (TRUE);
  697. }
  698.  
  699. /* using - get form definition file spec */
  700. static int using(pfp,ext)
  701.   FILE **pfp; char *ext;
  702. {
  703.     /* assume no using clause */
  704.     *pfp = NULL;
  705.  
  706.     /* check for "using <fname>" */
  707.     if (db_token() != USING)
  708.         return (TRUE);
  709.     db_ntoken();
  710.     if (db_ntoken() == ID)
  711.         strcat(dbv_tstring,ext);
  712.     else if (dbv_token != STRING)
  713.         return (db_ferror(SYNTAX));
  714.  
  715.     /* open the input file */
  716.     if ((*pfp = fopen(dbv_tstring,"r")) == NULL)
  717.         return (db_ferror(INPFNF));
  718.  
  719.     /* return successfully */
  720.     return (TRUE);
  721. }
  722.  
  723. /* table - output a relation table */
  724. static int table(fp,slptr)
  725.   FILE *fp; struct sel *slptr;
  726. {
  727.     int tcnt;
  728.  
  729.     /* loop through the selected tuples */
  730.     for (tcnt = 0; db_fetch(slptr); tcnt++) {
  731.  
  732.         /* print table head on first tuple selected */
  733.         if (tcnt == 0)
  734.             db_thead(fp,slptr);
  735.  
  736.         /* print the tuple */
  737.         db_tentry(fp,slptr);
  738.     }
  739.  
  740.     /* print table foot */
  741.     if (tcnt != 0)
  742.         db_tfoot(fp,slptr);
  743.  
  744.     /* return the tuple count */
  745.     return (tcnt);
  746. }
  747.  
  748. /* form - process a form */
  749. static int form(ofp,slptr,ffp)
  750.   FILE *ofp; struct sel *slptr; FILE *ffp;
  751. {
  752.     char aname[ANSIZE+1];
  753.     int ch,tcnt;
  754.  
  755.     /* loop through the selected tuples */
  756.     for (tcnt = 0; db_fetch(slptr); tcnt++) {
  757.  
  758.         /* reposition the form definition file */
  759.         fseek(ffp,0L,0);
  760.  
  761.         /* process the form */
  762.         while ((ch = getc(ffp)) != -1)
  763.             if (ch == '<') {
  764.                 get_aname(ffp,aname);
  765.                 put_avalue(ofp,slptr,aname);
  766.             }
  767.             else
  768.                 putc(ch,ofp);
  769.     }
  770.  
  771.     /* return the tuple count */
  772.     return (tcnt);
  773. }
  774.  
  775. /* get_aname - get an attribute name */
  776. static get_aname(fp,aname)
  777.   FILE *fp; char *aname;
  778. {
  779.     int ch;
  780.  
  781.     while ((ch = getc(fp)) != '>')
  782.         if (!isspace(ch))
  783.             *aname++ = ch;
  784.     *aname = 0;
  785. }
  786.  
  787. /* put_avalue - output attribute value */
  788. static put_avalue(fp,slptr,aname)
  789.   FILE *fp; struct sel *slptr; char *aname;
  790. {
  791.     struct sattr *saptr;
  792.     char *saname;
  793.     int i;
  794.  
  795.     /* loop through the selected attributes */
  796.     for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) {
  797.  
  798.         /* check the selected attribute name */
  799.         if ((saname = saptr->sa_name) == NULL)
  800.             saname = saptr->sa_aname;
  801.         if (db_scmp(saname,aname) == 0)
  802.             break;
  803.     }
  804.  
  805.     if (saptr == NULL) {
  806.         fprintf(fp,"<error>");
  807.         return;
  808.     }
  809.  
  810.     /* get the attribute value */
  811.     for (i = 0; i < saptr->sa_attr->at_size; i++)
  812.         if (saptr->sa_aptr[i] != 0)
  813.             putc(saptr->sa_aptr[i],fp);
  814.         else
  815.             putc(' ',fp);
  816. }
  817.  
  818. /* set - set internal parameters */
  819. static int set()
  820. {
  821.     int value;
  822.  
  823.     /* process each set request */
  824.     while (db_token() == ID) {
  825.  
  826.         /* skip the identifier */
  827.         db_ntoken();
  828.  
  829.         /* check for "no" */
  830.         if (db_scmp(dbv_tstring,"no") == 0) {
  831.             value = FALSE;
  832.             if (db_token() != ID)
  833.                 return (db_ferror(BADSET));
  834.             db_ntoken();
  835.         }
  836.         else
  837.             value = TRUE;
  838.  
  839.         /* check for parameter to set */
  840.         if (db_scmp(dbv_tstring,"fold") == 0)
  841.             dbv_fold = value;
  842.         else
  843.             return (db_ferror(BADSET));
  844.     }
  845.  
  846.     /* return successfully */
  847.     return (TRUE);
  848. }
  849.  
  850.